[2015_defcamp] [REV] Entry language¶
Flow Chart¶
File Type¶
파일 하나를 주네요. file로 어떤 형식인지 살펴봅니다.
$ file ./r100
./r100: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.24,
BuildID[sha1]=0x2448460f21e38ecca7809aef1b0bc7996881ec6a, stripped
stripped가 된 elf파일이기에 strace로 바이너리를 추적해봅니다.
$ strace ./r100
ptrace(PTRACE_TRACEME, 0, 0, 0) = -1 EPERM (Operation not permitted)
gdb로 디버깅 할 때 루프가 발생하도록 ptrace명령을 박아두었습니다.
IDA¶
IDA hexray decompiler로 확인해봅니다.
먼저 start 함수 부분을 찾아 rdi로 이동하는 주소를 찾습니다.
그 주소가 바로 main 입니다. F5로 pseudo 코드를 보도록 하겠습니다.
sub_4007E8 (main)¶
signed __int64 sub_4007E8()
{
signed __int64 result; // rax@3
__int64 v1; // rcx@6
char s; // [sp+0h][bp-110h]@1
__int64 v3; // [sp+108h][bp-8h]@1
v3 = *MK_FP(__FS__, 40LL);
printf("Enter thepassword: ");
if ( fgets(&s, 255, stdin) )
{
if ( sub_4006FD(&s, 255LL) )
{
puts("Incorrectpassword!");
result = 1LL;
}
else
{
puts("Nice!");
result = 0LL;
}
}
else
{
result = 0LL;
}
v1 = *MK_FP(__FS__, 40LL) ^ v3;
return result;
}
sub_4006FD¶
Nice가 나와야 하기 때문에 아마도 sub_4006FD에서 False(0)이면 될 것입니다.
sub_4006FD 함수를 따라가 봅니다.
signed __int64 __fastcall sub_4006FD(__int64 a1)
{
signed int i; // [sp+14h] [bp-24h]@1
char v3[8]; // [sp+18h] [bp-20h]@1
char v4[8]; // [sp+20h] [bp-18h]@1
char v5[8]; // [sp+28h] [bp-10h]@1
*(_QWORD *)v3 = "Dufhbmf";
*(_QWORD *)v4 = "pG`imos";
*(_QWORD *)v5 = "ewUglpt";
for ( i = 0; i <= 11; ++i )
{
if ( *(_BYTE *)(*(_QWORD *)&v3[8 * (i % 3)] + 2 * (i / 3)) - *(_BYTE *)(i + a1) != 1 )
return 1LL;
}
return 0LL;
}